
package dsc;

import java.lang.management.ManagementFactory;
import java.net.*;
import java.util.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * De main hier begint de server. De threads op die nodig zijn
 * voor het programma worden hier opgestart. Dat er zijn
 * in dit geval 3 threads: de listener, de messagehandler en
 * de pinger. Ook wordt er een logger en een \verb|DataStorage| instantie
 * aangemaakt.
 */

public class Main {

    protected static int UDP_PORT = 2011;
    protected static InetAddress csAddress;
    protected static int csPort;
    protected static String ident;
    protected static Level LEVEL;

    /**
     * Hier wordt de server indent gemaakt we hebben gekozen om maar een beperkt
     * aantal characters uit asci te gebruiken om deze unieke server
     * Identificatie uit op te bouwen.
     */
    protected static String makeServerIdent() {
        Random random = new Random();
        String randomstring = "";
        String[] name = ManagementFactory.getRuntimeMXBean().getName().split(
                "@");
        String processid = name[0];
        String teamnummer = "08";
        String serverident = "T" + teamnummer + "S" + processid;
        byte[] bytes = new byte[32 - serverident.getBytes().length];

        for (int i = 0; i < bytes.length; i++) {
            int temp = Math.abs((random.nextInt() % 57)) + 65;
            char temp1 = (char) temp;
            randomstring += Character.toString(temp1);
        }
        return ident = serverident + randomstring;
    }

    /**
     * Het mainprogramma dat alle threads opstart om de server te runnen
     *
     * @param args
     * @throws Exception
     */
    public static void main(String args[]) throws Exception {

        DatagramSocket serverSocket;

        List<String> list = new ArrayList<String>();
        DataStorage ds = new DataStorage();

        /* Maak logger aan */
        Logging logInstance = new Logging(Main.class.getName());
        Logger logger = logInstance.createLogger();

        try {
            logInstance.init(logger);
        } catch (Exception e) {
        }

        try {
            FileReader input = new FileReader("cfg" + File.separator
                    + "config.txt");
            BufferedReader bufRead = new BufferedReader(input);
            String line;

            do {
                line = bufRead.readLine();
                list.add(line);
            } while (line != null);

            bufRead.close();
            /*
             * Dit leest de config file uit.
             */
            for (int i = 0; i < list.size() - 1; i++) {
                String[] temp = list.get(i).split(":");

                if (temp[0].matches("port")) {
                    UDP_PORT = Integer.parseInt(temp[1]);

                } else if (temp[0].matches("controlserver")) {
                    csAddress = InetAddress.getByName(temp[1]);
                    csPort = Integer.parseInt(temp[2]);
                    logger.info("ControlServer addres: " + csAddress);
                } /*
                 * Het wachtwoord en de namen van de admins weet nog niet
                 * precies wat we hiermee moeten doen.
                 */ else if (temp[0].matches("admin")) {
                    ds.admins.add(temp[1] + " " + temp[2]);
                } else if (temp[0].matches("team")) {
                } else if (temp[0].matches("level")) {
                    LEVEL = Level.parse(temp[1]);
                } else {
                    /*
                     * logger warning invalid input in het config bestand.
                     */
                    logger.severe("Ongeldige waarde in de config.");
                }
            }

        } catch (Exception e) {
            logger.warning(e.getMessage());
        }
        /*
         * Open de poort waar je over gaat versturen en gaat luisteren.
         */
        serverSocket = new DatagramSocket(UDP_PORT);

        logger.info("ik ben nu naar poort " + UDP_PORT + " aan het luisteren");
        /*
         * Maak de Server Identifier aan.
         */

        String serverident = makeServerIdent();
        ident = serverident;
        logger.info(serverident);
        /*
         * misschien nog een writer om de informatie in de config file te
         * schrijven.
         */
        logger.info("Ik ben nu aan het runnen");

        /*
         * Maak alle objecten aan en start de threads.
         */
        MessageCreator creator = new MessageCreator(serverSocket);
        MessageHandler handler = new MessageHandler(creator, ds);
        Listener listener = new Listener(serverSocket, handler);
        Pinger pinger = new Pinger(creator);

        listener.start();
        handler.start();
        pinger.start();

        while (true) {
            /*
             * Blijf door gaan totdat er iets fout is gegaan binnen een van de
             * threads.
             */
            if (!(listener.isAlive() && handler.isAlive() && pinger.isAlive())) {
                logger.severe("Iemand is dood ik ga nu de poort sluiten.\n"
                        + " Listener alive? " + listener.isAlive() + "\n"
                        + " Handler alive? " + handler.isAlive() + "\n"
                        + " Pinger alive? " + pinger.isAlive());

                serverSocket.close();

                break;
            }
        }

        System.exit(1);
    }
}
